﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace thinger.MTHControlLib
{
    public partial class DialPlate : UserControl
    {
        public DialPlate()
        {
            InitializeComponent();
            //文本纵向居中
            stringFormat.LineAlignment = StringAlignment.Center;
            //文本横向居中
            stringFormat.Alignment = StringAlignment.Center;
        }

        private StringFormat stringFormat = new StringFormat();

        #region 外环

        private Color alarmColor = Color.FromArgb(36, 184, 196);
        [Browsable(true)]
        [Category("自定义属性")]
        [Description("警告环颜色")]
        public Color AlarmColor
        {
            get { return alarmColor; }
            set
            {
                alarmColor = value;
                this.Invalidate();//重绘
            }
        }

        private Color ringColor = Color.FromArgb(187, 187, 187);
        [Browsable(true)]
        [Category("自定义属性")]
        [Description("外环颜色")]
        public Color RingColor
        {
            get { return ringColor; }
            set
            {
                ringColor = value;
                this.Invalidate();//重绘
            }
        }
       
        private float alarmAngle = 120f;
        [Browsable(true)]
        [Category("自定义属性")]
        [Description("警告角度")]
        public float AlarmAngle
        {
            get { return alarmAngle; }
            set
            {
                alarmAngle = value;
                this.Invalidate();//重绘
            }
        }


        private int outThinkness = 8;
        [Browsable(true)]
        [Category("自定义属性")]
        [Description("外环宽度")]
        public int OutThinkness
        {
            get { return outThinkness; }
            set
            {
                outThinkness = value;
                this.Invalidate();//重绘
            }
        }
        #endregion

        #region 内环
        private float tempScale = 0.8f;
        [Browsable(true)]
        [Category("自定义属性")]
        [Description("温度比例")]
        public float TempScale
        {
            get { return tempScale; }
            set
            {

                if (value < 0f || value > 1f) return;
                tempScale = value;
                this.Invalidate();//重绘
            }
        }
        private Color tempColor = Color.FromArgb(36, 184, 196);
        [Browsable(true)]
        [Category("自定义属性")]
        [Description("温度环颜色")]
        public Color TempColor
        {
            get { return tempColor; }
            set
            {
                tempColor = value;
                this.Invalidate();//重绘
            }
        }

        private float humidityScale = 0.4f;
        [Browsable(true)]
        [Category("自定义属性")]
        [Description("湿度环比例")]
        public float HumidityScale
        {
            get { return humidityScale; }
            set
            {
                if (value < 0f || value > 1f) return;
                humidityScale = value;
                this.Invalidate();
            }
        }

        private Color humidityColor = Color.FromArgb(36, 184, 196);
        [Browsable(true)]
        [Category("自定义属性")]
        [Description("湿度环比例")]
        public Color HumidityColor
        {
            get { return humidityColor; }
            set
            {
                humidityColor = value;
                this.Invalidate();
            }
        }

        private int inThinkness = 16;
        [Browsable(true)]
        [Category("自定义属性")]
        [Description("内环宽度")]
        public int InThinkness
        {
            get { return inThinkness; }
            set
            {
                inThinkness = value;
                this.Invalidate();
            }
        }

        #endregion

        #region 刻度盘

        private float rangaMin = 0;
        [Browsable(true)]
        [Category("自定义属性")]
        [Description("刻度下限")]
        public float RangaMin
        {
            get { return rangaMin; }
            set
            {
                if (value > rangaMax) return;
                rangaMin = value;
                this.Invalidate();
            }
        }

        private float rangaMax = 90f;
        [Browsable(true)]
        [Category("自定义属性")]
        [Description("刻度上限")]
        public float RangaMax
        {
            get { return rangaMax; }
            set
            {
                if (value < rangaMin) return;
                rangaMax = value;
                this.Invalidate();
            }
        }

        private float textScale = 0.85f;
        [Browsable(true)]
        [Category("自定义属性")]
        [Description("刻度环比例")]
        public float TextScale
        {
            get { return textScale; }
            set
            {
                textScale = value;
                this.Invalidate();
            }
        }


        #endregion

        #region 实时值
        private float temp = 10.0f;
        [Browsable(true)]
        [Category("自定义属性")]
        [Description("温度实施值")]
        public float Temp
        {
            get { return temp; }
            set
            {
                if (value < rangaMin)
                {
                    temp = rangaMin;
                }
                else if (value > rangaMax)
                {
                    temp = rangaMax;
                }
                else
                {
                    temp = value;
                }
                this.Invalidate();
            }
        }

        private float humidity = 10.0f;
        [Browsable(true)]
        [Category("自定义属性")]
        [Description("温度实施值")]
        public float Humidity
        {
            get { return humidity; }
            set
            {
                if (value < rangaMin)
                {
                    humidity = rangaMin;
                }
                else if (value > rangaMax)
                {
                    humidity = rangaMax;
                }
                else
                {
                    humidity = value;
                }
                this.Invalidate();
            }
        }

        #endregion
        //开始生命周期
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);


            Graphics graphics = e.Graphics;
            //要实现抗锯齿效果
            graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
            //绘制的文本将尝试利用ClearType效果（如果显示设备支持），从而使文本在LCD屏幕上看起来更加清晰和易读。
            graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;

            //异常处理
            if (this.Width <= 20 || this.Height <= 20) return;

            if (this.Height < this.Width / 2) return;
            //画外环的警告环
            Pen pen = new Pen(alarmColor, outThinkness);

            graphics.DrawArc(pen, new RectangleF(10, 10, this.Width - 20, this.Width - 20), 180, alarmAngle);
            //画外环剩余部分
            Pen penRing = new Pen(ringColor, outThinkness);
            graphics.DrawArc(penRing, new RectangleF(10, 10, this.Width - 20, this.Width - 20), 180 + alarmAngle, 180 - alarmAngle);


            //画刻度表

            //移动坐标系
            graphics.TranslateTransform(this.Width * 0.5f, this.Width * 0.5f);

            //旋转坐标系
            graphics.RotateTransform(-90);

            SolidBrush solidBrush;

            for (int i = 0; i < 7; i++)
            {
                if (i * 30 <= alarmAngle)
                {
                    solidBrush = new SolidBrush(alarmColor);
                }
                else
                {
                    solidBrush = new SolidBrush(ringColor);
                }

                float width = 6f;
                float height = outThinkness + 4;
                float x = -3f;
                float y = (this.Width * 0.5f - 10 + height * 0.5f) * (-1f);
                //绘制实心矩形
                graphics.FillRectangle(solidBrush, new RectangleF(x, y, width, height));

                //旋转坐标系
                graphics.RotateTransform(30);
            }

            //将坐标系转回去
            graphics.RotateTransform(-210);
            //再正转90度
            graphics.RotateTransform(90);

            //刻度文本
            //刻度的文本平均值
            float rangaAvg = (rangaMax - rangaMin) % 6 == 0 ? Convert.ToSingle((rangaMax - rangaMin) / 6) : Convert.ToSingle(((rangaMax - rangaMin) / 6).ToString("f1"));

            for (int i = 0; i < 7; i++)
            {
                float pointAngle = -180 + i * 30;
                float pointX = Convert.ToSingle((this.Width * 0.5f - 10f) * textScale * Math.Cos(pointAngle * Math.PI / 180));
                float pointY = Convert.ToSingle((this.Width * 0.5f - 10f) * textScale * Math.Sin(pointAngle * Math.PI / 180));

                string text = (rangaAvg * i).ToString();

                SizeF sizeF = graphics.MeasureString(text, this.Font);

                graphics.DrawString(text, this.Font, new SolidBrush(this.ForeColor),new RectangleF(pointX - sizeF.Width * 0.5f, pointY, sizeF.Width, sizeF.Height), stringFormat);
            }


            //温度环
            float tempX = (this.Width * 0.5f - 10f) * tempScale * (-1f);
            float tempY = (this.Width * 0.5f - 10f) * tempScale * (-1f);
            float tempAngle = temp / ((rangaMax - rangaMin) / 180);
            graphics.DrawArc(new Pen(tempColor, inThinkness), new RectangleF(tempX, tempY, (this.Width - 20) * tempScale, (this.Width - 20) * tempScale), 180, tempAngle);

            //湿度环
            float humidityX = (this.Width * 0.5f - 10f) * humidityScale * (-1f);
            float humidityY = (this.Width * 0.5f - 10f) * humidityScale * (-1f);
            float humidityAngle = humidity / ((rangaMax - rangaMin) / 180);
            graphics.DrawArc(new Pen(humidityColor, inThinkness), new RectangleF(humidityX, humidityY, (this.Width - 20) * humidityScale, (this.Width - 20) * humidityScale), 180, humidityAngle);
        }

    }
}
